package com.crossriver.crgis;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.TimeZone;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.util.CalendarFactoryUtil;
import com.liferay.portal.kernel.util.CalendarUtil;
import com.liferay.portal.kernel.util.DateUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.model.ListType;
import com.liferay.portal.service.ListTypeServiceUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

/**
 * Portlet implementation class Calculator
 */
public class Calculator extends MVCPortlet {
	
	public void submitTogetFees(ActionRequest request, ActionResponse res){
		
		String transactions = ParamUtil.getString(request, "transactions");
		List<ListType> mappedFees = new ArrayList<ListType>();
		
		List<ListType> temp_mappedFees = new ArrayList<ListType>();
		try {
			 mappedFees = ListTypeServiceUtil.getListTypes("com.teqbridgeltd.liferay.model.map." + transactions);

		} catch (SystemException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//403031, 403032, 403033, 403034, 403025
		int testFees = 28602;
		for(int i=0; i<mappedFees.size(); i++){
			ListType mappedFee = mappedFees.get(i);
			if(mappedFee.getListTypeId() == testFees){
				temp_mappedFees.add(mappedFee);
			}
			
		}
		
		request.setAttribute("mappedFees", mappedFees);
		request.setAttribute("transactions", transactions);

	}

	/**
	 * This method is used to override the addSuccessMessage in the parent
	 * class. This override ensures that success message (that is displayed as
	 * default whenever any request is successfully submitted) is prevented.
	 * 
	 * We like to have control over this and this what this override ensures.
	 * 
	 */
	@Override
	protected void addSuccessMessage(ActionRequest actionRequest,
			ActionResponse actionResponse) {

		if (!addProcessActionSuccessMessage) {
			return;
		}
	}
	
	@Override
	public void serveResource(
			ResourceRequest resourceRequest, ResourceResponse resourceResponse)
		throws IOException, PortletException {
				resourceRequest.getAttributeNames();
		
		String res = "";
				
		Enumeration<String> params = resourceRequest.getParameterNames();
		while (params.hasMoreElements()) {
			String string = (String) params.nextElement();
		}
		
		String queryType= ParamUtil.getString(resourceRequest, "queryType"); // resourceRequest.getParameter("queryType") ;
	
		JSONObject jsonFeed = JSONFactoryUtil.createJSONObject();
			if ("lga".equalsIgnoreCase(queryType)){
				try {
					String stateName =  ParamUtil.getString(resourceRequest, "stateName");  //resourceRequest.getParameter("stateName") ;
					if (stateName.equalsIgnoreCase(stateName)){
						List<ListType> states = ListTypeServiceUtil.getListTypes("com.teqbridgeltd.liferay.model.lga." + stateName );
						
						int stateId = 1;
						for (Iterator iterator = states.iterator(); iterator.hasNext();) {
							
							String sStateId = "param_" + stateId;
							ListType listType = (ListType) iterator.next();
							
							jsonFeed.put(sStateId, listType.getName());
							stateId = stateId + 1;
						}
						
						jsonFeed.put("stateId", stateId-1);
						
					}
					else
					{
						jsonFeed.put("stateId", 0);
					}
						

					
				} catch (SystemException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			else if ("states".equalsIgnoreCase(queryType))
			{
				try {
					String country = ParamUtil.getString(resourceRequest, "countryName");// resourceRequest.getParameter("countryName") ;
					if ("nigeria".equalsIgnoreCase(country)){
						List<ListType> states = ListTypeServiceUtil.getListTypes("com.teqbridgeltd.liferay.model.state");
						
						int stateId = 1;
						for (Iterator iterator = states.iterator(); iterator.hasNext();) {
							
							String sStateId = "param_" + stateId;
							ListType listType = (ListType) iterator.next();
							
							jsonFeed.put(sStateId, listType.getName());
							stateId = stateId + 1;
						}
						
						jsonFeed.put("stateId", stateId-1);
						
					}
					else
					{
						jsonFeed.put("stateId", 0);
					}
						

					
				} catch (SystemException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			else if ("landUse".equalsIgnoreCase(queryType))
			{
					try {
						String landUse =  ParamUtil.getString(resourceRequest, "landUse");  //resourceRequest.getParameter("stateName") ;
						if (landUse.equalsIgnoreCase(landUse)){  //TODO change the variable name
							List<ListType> states = ListTypeServiceUtil.getListTypes("com.teqbridgeltd.liferay.model.land_use." + landUse );
							
							int purposeId = 1;
							for (Iterator iterator = states.iterator(); iterator.hasNext();) {
								
								String sPurposeId = "param_" + purposeId;
								String sPurposeCode = "purposeCode_" + purposeId;
								
								ListType listType = (ListType) iterator.next();
								
								String name = listType.getName();
								StringTokenizer nameTok = new StringTokenizer(name, "~");
								String purpose = "";
								if(nameTok.hasMoreTokens()){
									purpose = nameTok.nextToken();
								}else{
									purpose = name;
								}
								
								String purposeCode = "";
								if(nameTok.hasMoreTokens()){
									purposeCode = nameTok.nextToken();
								}else{
									purposeCode = name;
								}
								
								jsonFeed.put(sPurposeId, purpose);
								jsonFeed.put(sPurposeCode, purposeCode);
								purposeId = purposeId + 1;
							}
							
							jsonFeed.put("purposeId", purposeId-1);
							
						}
						else
						{
							jsonFeed.put("purposeId", 0);
						}
							

						
					} 
					catch (SystemException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}else if ("groundRentRate".equalsIgnoreCase(queryType)){
					String propertyType =  ParamUtil.getString(resourceRequest, "propertyType");
					String useType =  ParamUtil.getString(resourceRequest, "useType");
					String purpose =  ParamUtil.getString(resourceRequest, "purpose");
					int lastPaymentYear =  ParamUtil.getInteger(resourceRequest, "lastPaymentYear");
					double area =  ParamUtil.getDouble(resourceRequest, "area");
					String layout = ParamUtil.getString(resourceRequest, "layout");
					
					
					int yearToPay = lastPaymentYear + 1;
					
					BigDecimal groundRent = new BigDecimal(0);
					BigDecimal penalty = new BigDecimal(0);
					
					while(yearToPay <= 2012){
						///1983.2003.StateLand.RES.groundrent.ESUK UTAN
						String queryCriteria = "";
						
						
						
						if(yearToPay >=1983 && yearToPay <= 2003){
							queryCriteria = queryCriteria + "1983.2003.";
						}else if(yearToPay >=2004 && yearToPay <= 2011){
							queryCriteria = queryCriteria + "2004.2011.";
						}else if (yearToPay >=2012 && yearToPay <= 2012){
							queryCriteria = queryCriteria + "2012.2012.";
						}
						
						if ("Government".equalsIgnoreCase(propertyType)){
							queryCriteria = queryCriteria + "StateLand.";
						}else{
							queryCriteria = queryCriteria + "Private.";
						}
						
						//TO DO ... add other ones here
						String sUseType = getUseType(yearToPay, useType, purpose );
						
						queryCriteria = queryCriteria + sUseType + ".groundrent." + layout;
						
						//String type_ = "1983.2003."+ StateLand.RES.groundrent.ESUK UTAN";
						
						List<ListType> listTypes = null;
						try {
							listTypes = ListTypeServiceUtil.getListTypes(queryCriteria);
						} catch (SystemException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						if(listTypes == null || listTypes.size() ==0){
							
						}else{
							ListType listType = listTypes.get(0);
							double rate = new Double(listType.getName()).doubleValue(); 
							
							if(yearToPay < 2012){
								//after adjusting for the missing thousand 
								rate = rate * 1000;
							}
							BigDecimal yearGrRent = new BigDecimal(rate * area  );
							
							
							groundRent = groundRent.add(yearGrRent);
							
							String year = DateUtil.getCurrentDate("yyyy", resourceRequest.getLocale());
							
							if(year.equalsIgnoreCase(new Integer(yearToPay).toString())){
								Calendar cal = CalendarFactoryUtil.getCalendar(yearToPay, 01, 01);
								
								int days = DateUtil.getDaysBetween(cal.getTime(), 
										CalendarFactoryUtil.getCalendar().getTime(),
										TimeZone.getDefault());
								
								if(days >= 60){
									penalty = groundRent.multiply(new BigDecimal(0.05) );
								}else if(days >= 90) {
									penalty = groundRent.multiply(new BigDecimal(0.1) );
								}
							}else{
								penalty = groundRent.multiply(new BigDecimal(0.1) );
							}
							
						}
						
						yearToPay += 1;
					}
					
					Double dGroundRent = groundRent.doubleValue();
					Double dPenalty = penalty.doubleValue();
					
					jsonFeed.put("groundRent", dGroundRent);
					jsonFeed.put("penalty", dPenalty);

				}else if ("getDevLevyRate".equalsIgnoreCase(queryType)){
					
					String useType =  ParamUtil.getString(resourceRequest, "useType");
					double area =  ParamUtil.getDouble(resourceRequest, "area");
					String layout = ParamUtil.getString(resourceRequest, "layout");
					
					//dev.levy.dlpi
					String devLevyUseCode = useTypeDevLevyLookup(useType);
					
					String queryCriteria = "dev.levy." +devLevyUseCode ;

					List<ListType> listTypes = null;
					try {
						listTypes = ListTypeServiceUtil.getListTypes(queryCriteria);
					} catch (SystemException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					double devLevy =0;
					if(null != listTypes && listTypes.size()>0 ){
						ListType listType = listTypes.get(0);
						
						StringTokenizer strTok = new StringTokenizer(listType.getName(), "|");
						devLevy = area * new Double(strTok.nextToken()).doubleValue();
					}
					
					jsonFeed.put("devLevy", devLevy);
					
					
				}else if ("getPremFeesRate".equalsIgnoreCase(queryType)){
					
					String useType =  ParamUtil.getString(resourceRequest, "useType");
					double area =  ParamUtil.getDouble(resourceRequest, "area");
					String layout = ParamUtil.getString(resourceRequest, "layout");
					
					//dev.levy.dlpi
					String devLevyUseCode = useTypePremiumFeesLookup(useType);
					
					String queryCriteria = "premium.fees." +devLevyUseCode ;
 
					List<ListType> listTypes = null;
					try {
						listTypes = ListTypeServiceUtil.getListTypes(queryCriteria);
					} catch (SystemException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					double premFees =0;
					
					//get the premium from the list
					double premRate = getPremiumFromlist(listTypes, layout, devLevyUseCode);
					premFees = area * premRate;
					
					jsonFeed.put("premFees", premFees);
					
					
				}
	
		res = "'{\"result\":true,\"count\":1}'";
		resourceResponse.setContentType("text/html");


		resourceResponse.getWriter().println(jsonFeed.toString());
	}
	
	private double getPremiumFromlist(List<ListType> prems, String layout, String use_type){
		
		boolean found = false;
		for (int i=0; i<prems.size(); i++){
			ListType prem = prems.get(i);
			
			String name = prem.getName();
			if(name.indexOf(layout) >=1 &&name.indexOf(layout) >=1 ){
				StringTokenizer strTok = new StringTokenizer(name, "|");
				
				return new Double(strTok.nextToken()).doubleValue();
			}
			
		}
		
		
		return 0.0;
	}
	
	private String getUseType(int yearToPay, String useType, String purpose){
		String sUseType = useType;
		
		
		if(yearToPay >=1983 && yearToPay <= 2003){
			sUseType = useTypeLookup(useType);
		}else if(yearToPay >=2004 && yearToPay <= 2011){
			sUseType = useTypeLookup(useType);
		}else if (yearToPay >=2012 && yearToPay <= 2012){
			sUseType = useTypeLookup(useType);
		}
		
		return sUseType;
	}
	
	private String useTypePremiumFeesLookup(String useType){
		if("AGRICULTURAL AND MIXED USE".equalsIgnoreCase(useType)){
			return "PCAM";
		}
		if("COMMERCIAL".equalsIgnoreCase(useType)){
			return "PCCI";
		}
		
		if("INDUSTRIAL".equalsIgnoreCase(useType)){
			return "PCCI";
		}
		
		if("OPEN SPACE OR GREEN AREA".equalsIgnoreCase(useType)){
			return "PCOG";
		}
		
		if("PUBLIC INSTITUTION".equalsIgnoreCase(useType)){
			return "PCPI";
		}
		
		if("PUBLIC UTILITY".equalsIgnoreCase(useType)){
			return "PCPI";
		}
		
		if("RESIDENTIAL".equalsIgnoreCase(useType)){
			return "PCR";
		}
		
		
		if("TRANSPORTATION".equalsIgnoreCase(useType)){
			return "PCT";
		}
		
		return useType;
	}

	private String useTypeDevLevyLookup(String useType){
		if("AGRICULTURAL AND MIXED USE".equalsIgnoreCase(useType)){
			return "DLAM";
		}
		if("COMMERCIAL".equalsIgnoreCase(useType)){
			return "DLCI";
		}
		
		if("INDUSTRIAL".equalsIgnoreCase(useType)){
			return "DLCI";
		}
		
		if("OPEN SPACE OR GREEN AREA".equalsIgnoreCase(useType)){
			return "DLOG";
		}
		
		if("PUBLIC INSTITUTION".equalsIgnoreCase(useType)){
			return "DLPI";
		}
		
		if("PUBLIC UTILITY".equalsIgnoreCase(useType)){
			return "DLPI";
		}
		
		if("RESIDENTIAL".equalsIgnoreCase(useType)){
			return "DLR";
		}
		
		
		if("TRANSPORTATION".equalsIgnoreCase(useType)){
			return "DLT";
		}
		
		return useType;
	}
	
	private String useTypeLookup(String useType){
		if("AGRICULTURAL AND MIXED USE".equalsIgnoreCase(useType)){
			return "AGR";
		}
		if("COMMERCIAL".equalsIgnoreCase(useType)){
			return "COM";
		}
		
		if("INDUSTRIAL".equalsIgnoreCase(useType)){
			return "HI";
		}
		
		if("OPEN SPACE OR GREEN AREA".equalsIgnoreCase(useType)){
			return "OS";
		}
		
		if("PUBLIC INSTITUTION".equalsIgnoreCase(useType)){
			return "PI";
		}
		
		if("PUBLIC UTILITY".equalsIgnoreCase(useType)){
			return "PUU";
		}
		
		if("RESIDENTIAL".equalsIgnoreCase(useType)){
			return "RES";
		}
		
		
		if("TRANSPORTATION".equalsIgnoreCase(useType)){
			return "T";
		}
		
		return useType;
	}
}
